<?php

namespace App\Services;

use App\Exceptions\AuthException;
use App\Models\ZZMed\XDocLogin;
use Carbon\Carbon;

/**
 *  登录授权机制 参考patient-api
 * Class AuthService
 * @package App\Services
 */
class AuthService
{

    protected static $guard = 'api';

    /**
     * 获取guard
     * @return string
     */
    public static function getGuard()
    {
        return self::$guard;
    }

    /**
     * 用户授权token
     * @param $userIp
     * @param $user
     * @return array
     * @throws \Exception
     */
    public function authTokenByUser($appInfo, $userIp, $user)
    {
        if (!$user) {
            throw new AuthException('用户信息不存在,请核对后重试');
        }
        $appId = $appInfo['zz_app_id'] ?? '';
        // 如果用户还有效期至少7天的token 返回token
        $oldToken = XDocLogin::query()
            ->select('user_id', 'access_token', 'token_type', 'expires_in')
            ->where('user_id', $user->id)
            ->where('zz_app_id', $appId)
            ->where('expires_at', '>', Carbon::now()->addDays(7))
            ->orderBy('created_at', 'desc')
            ->first();

        if ($oldToken) {
            $tokenArr = $oldToken->toArray();
        } else {
            $tokenArr = $this->authToken($appInfo, $userIp, $user);
        }
        return $tokenArr;
    }


    /**
     *  生成token并记录登录log
     * @param $appInfo
     * @param $userIp
     * @param $user
     * @return array
     * @throws \Exception
     */
    public function authToken($appInfo, $userIp, $user)
    {
        $appName = $appInfo['zz_app_name'] ?? '';
        $res = [
            'user_id' => $user->id,
            'access_token' => $this->createToken($appName, $user),
            'token_type' => 'bearer',
            'expires_in' => auth(self::getGuard())->factory()->getTTL() * 60
        ];

        $this->markLogin($appInfo, $userIp, $res);
        return $res;
    }

    /**
     *  创建token
     * @param $appName
     * @param $user
     * @throws \Exception
     */
    protected function createToken($appName, $user)
    {
        if (! $token = auth(self::getGuard())->login($user)) {
            throw new \Exception('Create Authorize failed!');
        }
        return $token;
    }


    /**
     *  记录登录日志
     * @param $appId
     * @param $userIp
     * @param $loginRes
     * @return mixed
     */
    public function markLogin($appInfo, $userIp, $loginRes)
    {
        $loginRes['zz_app_id'] = $appInfo['zz_app_id'] ?? '180001';
        $loginRes['zz_app_client_version'] = $appInfo['zz_app_client_version'] ?? '';
        $loginRes['user_ip'] = $userIp;
        $loginRes['expires_at'] = Carbon::now()->addSeconds($loginRes['expires_in'] - 5);
        return XDocLogin::query()->create($loginRes);
    }




}
